home *** CD-ROM | disk | FTP | other *** search
/ BMUG PD-ROM 1995 Fall / PD-ROM F95.toast / Programming / Programming Languages / UCB Logo 3.0 ƒ / sources / standard source / files.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-14  |  10.1 KB  |  498 lines  |  [TEXT/ttxt]

  1. /*
  2.  *      files.c         logo file management module             dvb
  3.  *
  4.  *    Copyright (C) 1993 by the Regents of the University of California
  5.  *
  6.  *      This program is free software; you can redistribute it and/or modify
  7.  *      it under the terms of the GNU General Public License as published by
  8.  *      the Free Software Foundation; either version 2 of the License, or
  9.  *      (at your option) any later version.
  10.  *  
  11.  *      This program is distributed in the hope that it will be useful,
  12.  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *      GNU General Public License for more details.
  15.  *  
  16.  *      You should have received a copy of the GNU General Public License
  17.  *      along with this program; if not, write to the Free Software
  18.  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  */
  21.  
  22. #include "logo.h"
  23. #include "globals.h"
  24. #ifdef unix
  25. #include <sgtty.h>
  26. #endif
  27.  
  28. #ifdef mac
  29. #include <console.h>
  30. #endif
  31. #ifdef ibm
  32. #include <bios.h>
  33. #ifndef __ZTC__
  34. #include <alloc.h>
  35. #endif
  36. extern int getch(), kbhit();
  37. #ifdef __ZTC__
  38. #include <conio.h>
  39. #endif
  40. #endif
  41.  
  42. #ifndef TIOCSTI
  43. #include <setjmp.h>
  44. extern jmp_buf iblk_buf;
  45. #endif
  46.  
  47. NODE *file_list = NULL;
  48. NODE *reader_name = NIL, *writer_name = NIL;
  49.  
  50. FILE *open_file(NODE *arg, char *access)
  51. {
  52.     char *fnstr;
  53.     FILE *tstrm;
  54.  
  55.     ref(arg);
  56.     arg = reref(arg, cnv_node_to_strnode(arg));
  57.     if (arg == UNBOUND) return(NULL);
  58.     fnstr = (char *) malloc((size_t)getstrlen(arg) + 1);
  59.     strnzcpy(fnstr, getstrptr(arg), getstrlen(arg));
  60.     tstrm = fopen(fnstr, access);
  61.     deref(arg);
  62.     free(fnstr);
  63.     return(tstrm);
  64. }
  65.  
  66. NODE *ldribble(NODE *arg)
  67. {
  68.     if (dribblestream != NULL)
  69.     err_logo(ALREADY_DRIBBLING, NIL);
  70.     else {
  71.     dribblestream = open_file(car(arg), "w+");
  72.     if (dribblestream == NULL) err_logo(FILE_ERROR, NIL);
  73.     }
  74.     return(UNBOUND);
  75. }
  76.  
  77. NODE *lnodribble()
  78. {
  79.     if (dribblestream != NULL) {
  80.     fclose(dribblestream);
  81.     dribblestream = NULL;
  82.     }
  83.     return(UNBOUND);
  84. }
  85.  
  86. FILE *find_file(NODE *arg, BOOLEAN remove)
  87. {
  88.     NODE *t, *prev = NIL;
  89.     FILE *fp = NULL;
  90.  
  91.     t = file_list;
  92.     while (t != NIL) {
  93.     if (compare_node(arg, car(t), FALSE) == 0) {
  94.         fp = (FILE *)t->n_obj;
  95.         if (remove) {
  96.         t->n_obj = NIL;
  97.         if (prev == NIL)
  98.             file_list = reref(file_list, cdr(t));
  99.         else
  100.             setcdr(prev, cdr(t));
  101.         }
  102.         break;
  103.     }
  104.     prev = t;
  105.     t = cdr(t);
  106.     }
  107.     return fp;
  108. }
  109.  
  110. NODE *lopen(NODE *arg, char *mode)
  111. {
  112.     FILE *tmp;
  113.  
  114.     arg = car(arg);
  115.     if (find_file(arg, FALSE) != NULL)
  116.     err_logo(FILE_ERROR, make_static_strnode("File already open"));
  117.     else if ((tmp = open_file(arg, mode)) != NULL) {
  118.     push(arg, file_list);
  119.     file_list->n_obj = (NODE *) tmp;
  120.     }
  121.     else
  122.     err_logo(FILE_ERROR, make_static_strnode("I can't open that file"));
  123.     return(UNBOUND);
  124. }
  125.  
  126. NODE *lopenread(NODE *arg)
  127. {
  128.     return(lopen(arg,"r"));
  129. }
  130.  
  131. NODE *lopenwrite(NODE *arg)
  132. {
  133.     return(lopen(arg,"w"));
  134. }
  135.  
  136. NODE *lopenappend(NODE *arg)
  137. {
  138.     return(lopen(arg,"a"));
  139. }
  140.  
  141. NODE *lopenupdate(NODE *arg)
  142. {
  143.     return(lopen(arg,"a+"));
  144. }
  145.  
  146. NODE *lallopen()
  147. {
  148.     return(file_list);
  149. }
  150.  
  151. NODE *lclose(NODE *arg)
  152. {
  153.     FILE *tmp;
  154.  
  155.     if ((tmp = find_file(car(arg), TRUE)) == NULL)
  156.     err_logo(FILE_ERROR, make_static_strnode("File not open"));
  157.     else
  158.     fclose(tmp);
  159.     return(UNBOUND);
  160. }
  161.  
  162. NODE *lsetwrite(NODE *arg)
  163. {
  164.     FILE *tmp;
  165.  
  166.     if (car(arg) == NIL) {
  167.     writestream = stdout;
  168.     deref(writer_name);
  169.     writer_name = NIL;
  170.     }
  171.     else if ((tmp = find_file(car(arg), FALSE)) != NULL) {
  172.     writestream = tmp;
  173.     writer_name = reref(writer_name, car(arg));
  174.     }
  175.     else
  176.     err_logo(FILE_ERROR, make_static_strnode("File not open"));
  177.     return(UNBOUND);
  178. }
  179.  
  180. NODE *lsetread(NODE *arg)
  181. {
  182.     FILE *tmp;
  183.  
  184.     if (car(arg) == NIL) {
  185.     readstream = stdin;
  186.     deref(reader_name);
  187.     reader_name = NIL;
  188.     }
  189.     else if ((tmp = find_file(car(arg), FALSE)) != NULL) {
  190.     readstream = tmp;
  191.     reader_name = reref(reader_name, car(arg));
  192.     }
  193.     else
  194.     err_logo(FILE_ERROR, make_static_strnode("File not open"));
  195.     return(UNBOUND);
  196. }
  197.  
  198. NODE *lreader()
  199. {
  200.     return(reader_name);
  201. }
  202.  
  203. NODE *lwriter()
  204. {
  205.     return(writer_name);
  206. }
  207.  
  208. NODE *lerasefile(NODE *arg)
  209. {
  210.     char *fnstr;
  211.  
  212.     arg = cnv_node_to_strnode(car(arg));
  213.     if (arg == UNBOUND) return(UNBOUND);
  214.     fnstr = malloc((size_t)getstrlen(arg) + 1);
  215.     strnzcpy(fnstr, getstrptr(arg), getstrlen(arg));
  216.     unlink(fnstr);
  217.     free(fnstr);
  218.     return(UNBOUND);
  219. }
  220.  
  221. NODE *lsave(NODE *arg)
  222. {
  223.     FILE *tmp;
  224.  
  225.     tmp = writestream;
  226.     writestream = open_file(car(arg), "w+");
  227.     if (writestream != NULL) {
  228.     setcar(arg, cons(lcontents(), NIL));
  229.     lpo(car(arg));
  230.     fclose(writestream);
  231.     }
  232.     else
  233.     err_logo(FILE_ERROR, make_static_strnode("Could not open file"));
  234.     writestream = tmp;
  235.     return(UNBOUND);
  236. }
  237.  
  238. void runstartup(NODE *oldst)
  239. {
  240.     NODE *st;
  241.  
  242.     st = valnode__caseobj(Startup);
  243.     if (st != oldst && st != NIL && is_list(st)) {
  244.     val_status = 0;
  245.     eval_driver(st);
  246.     }
  247. }
  248.  
  249. void silent_load(NODE *arg, char *prefix)
  250. {
  251.     FILE *tmp_stream;
  252.     NODE *tmp_line, *exec_list;
  253.     char load_path[200];
  254.     NODE *st = valnode__caseobj(Startup);
  255.     int sv_val_status = val_status;
  256.  
  257.     /* This procedure is called three ways:
  258.      *    silent_load(NIL,*argv)    loads *argv
  259.      *    silent_load(proc,logolib)     loads logolib/proc
  260.      *    silent_load(proc,NULL)    loads proc.lg
  261.      * The "/" or ".lg" is supplied by this procedure as needed.
  262.      */
  263.  
  264.     if (prefix == NULL && arg == NIL) return;
  265.     strcpy(load_path, (prefix == NULL ? "" : prefix));
  266.     if (arg != NIL) {
  267.     arg = cnv_node_to_strnode(arg);
  268.     if (arg == UNBOUND) return;
  269. #ifdef unix
  270.     if (prefix != NULL) strcat(load_path, "/");
  271. #endif
  272.     noparitylow_strnzcpy(load_path + (int)strlen(load_path),
  273.                  getstrptr(arg), getstrlen(arg));
  274.     if (prefix == NULL) strcat(load_path, ".lg");
  275.     gcref(arg);
  276.     }
  277.     tmp_stream = loadstream;
  278.     tmp_line = vref(current_line);
  279.     loadstream = fopen(load_path, "r");
  280.     if (loadstream != NULL) {
  281.     while (!feof(loadstream) && NOT_THROWING) {
  282.         current_line = reref(current_line, reader(loadstream, ""));
  283.         exec_list =parser(current_line, TRUE);
  284.         val_status = 0;
  285.         if (exec_list != NIL) eval_driver(exec_list);
  286.     }
  287.     fclose(loadstream);
  288.     runstartup(st);
  289.     val_status = sv_val_status;
  290.     } else if (arg == NIL) ndprintf(stdout,"File not found: %t\n", prefix);
  291.     loadstream = tmp_stream;
  292.     deref(current_line);
  293.     current_line = tmp_line;
  294. }
  295.  
  296. NODE *lload(NODE *arg)
  297. {
  298.     FILE *tmp;
  299.     NODE *tmp_line, *exec_list;
  300.     NODE *st = valnode__caseobj(Startup);
  301.     int sv_val_status = val_status;
  302.  
  303.     tmp = loadstream;
  304.     tmp_line = vref(current_line);
  305.     loadstream = open_file(car(arg), "r");
  306.     if (loadstream != NULL) {
  307.     while (!feof(loadstream) && NOT_THROWING) {
  308.         current_line = reref(current_line, reader(loadstream, ""));
  309.         exec_list = parser(current_line, TRUE);
  310.         val_status = 0;
  311.         if (exec_list != NIL) eval_driver(exec_list);
  312.     }
  313.     fclose(loadstream);
  314.     runstartup(st);
  315.     val_status = sv_val_status;
  316.     } else
  317.     err_logo(FILE_ERROR, make_static_strnode("Could not open file"));
  318.     loadstream = tmp;
  319.     deref(current_line);
  320.     current_line = tmp_line;
  321.     return(UNBOUND);
  322. }
  323.  
  324. NODE *lreadlist()
  325. {
  326.     NODE *val;
  327.  
  328.     val = parser(reader(readstream, ""), FALSE);
  329.     if (feof(readstream)) {
  330.     gcref(val);
  331.     return(Null_Word);
  332.     }
  333.     return(val);
  334. }
  335.  
  336. NODE *lreadword()
  337. {
  338.     NODE *val;
  339.  
  340.     val = reader(readstream, "");
  341.     if (feof(readstream)) {
  342.     gcref(val);
  343.     return(NIL);
  344.     }
  345.     return(val);
  346. }
  347.  
  348. NODE *lreadchar()
  349. {
  350.     char c;
  351.  
  352.     charmode_on();
  353.     input_blocking++;
  354. #ifndef TIOCSTI
  355.     if (!setjmp(iblk_buf))
  356. #endif
  357. #ifdef mac
  358.     csetmode(C_RAW, stdin);
  359.     while ((c = (char)getc(readstream)) == EOF && readstream == stdin);
  360.     csetmode(C_ECHO, stdin);
  361. #else
  362. #ifdef ibm
  363.     if (interactive && readstream==stdin)
  364.     c = (char)getch();
  365.     else
  366.     c = (char)getc(readstream);
  367.  
  368.     if (c == 17) { /* control-q */
  369.     to_pending = 0;
  370.     err_logo(STOP_ERROR,NIL);
  371.     }
  372.     if (c == 23) { /* control-w */
  373.     logo_pause();
  374.     return(lreadchar());
  375.     }
  376. #else
  377.     c = (char)getc(readstream);
  378. #endif
  379. #endif
  380.     input_blocking = 0;
  381.     if (feof(readstream)) {
  382.     return(NIL);
  383.     }
  384.     return(make_strnode(&c, (char *)NULL, 1,
  385.         (getparity(c) ? STRING : BACKSLASH_STRING), strnzcpy));
  386. }
  387.  
  388. NODE *lreadchars(NODE *args)
  389. {
  390.     unsigned int c, i;
  391.     char *strhead, *strptr;
  392.     NODETYPES type = STRING;
  393.  
  394.     c = (unsigned int)getint(pos_int_arg(args));
  395.     if (stopping_flag == THROWING) return UNBOUND;
  396.     charmode_on();
  397.     input_blocking++;
  398. #ifndef TIOCSTI
  399.     if (!setjmp(iblk_buf))
  400. #endif
  401.     {
  402.     strhead = malloc((size_t)(c + 2));
  403.     strptr = strhead + 1;
  404.     fread(strptr, 1, (int)c, readstream);
  405.     setstrrefcnt(strhead, 0);
  406.     }
  407.     input_blocking = 0;
  408. #ifndef TIOCSTI
  409.     if (stopping_flag == THROWING) return(UNBOUND);
  410. #endif
  411.     if (feof(readstream)) {
  412.     free(strhead);
  413.     return(NIL);
  414.     }
  415.     for (i = 0; i < c; i++)
  416.     if (getparity(strptr[i])) type = BACKSLASH_STRING;
  417.     return(make_strnode(strptr, strhead, (int)c, type, strnzcpy));
  418. }
  419.  
  420. NODE *leofp()
  421. {
  422.     ungetc(getc(readstream),readstream);
  423.     if (feof(readstream))
  424.     return(True);
  425.     else
  426.     return(False);
  427. }
  428.  
  429. NODE *lkeyp()
  430. {
  431.     long nc;
  432. #ifdef mac
  433.     int c;
  434. #endif
  435.  
  436.     if (readstream == stdin && interactive) {
  437.     charmode_on();
  438.     fflush(stdout);
  439. #ifdef __ZTC__
  440.     zflush();
  441. #endif
  442. #if defined(mac)
  443.     csetmode(C_RAW, stdin);
  444.     c = ungetc(getc(readstream), readstream);
  445.     csetmode(C_ECHO, stdin);
  446.     return(c == EOF ? False : True);
  447. #elif defined(ibm)
  448.     return(kbhit() ? True : False);
  449. #else
  450. #ifdef FIONREAD
  451.     ioctl(0,FIONREAD,(char *)(&nc));
  452. #else
  453.     ndprintf(stdout,"Can't KEYP, no FIONREAD on this system\n");
  454.     nc = 1;    /* pretend there's a char so we don't loop */
  455. #endif
  456.     if (nc > 0)
  457.         return(True);
  458.     else
  459.         return(False);
  460. #endif
  461.     }
  462.     ungetc(getc(readstream),readstream);
  463.     if (feof(readstream))
  464.     return(True);
  465.     else
  466.     return(False);
  467. }
  468.  
  469. NODE *lreadpos()
  470. {
  471.     return(make_intnode(ftell(readstream)));
  472. }
  473.  
  474. NODE *lsetreadpos(NODE *arg)
  475. {
  476.     NODE *val = pos_int_arg(arg);
  477.  
  478.     if (NOT_THROWING) {
  479.     fseek(readstream,getint(val),0);
  480.     }
  481.     return(UNBOUND);
  482. }
  483.  
  484. NODE *lwritepos()
  485. {
  486.     return(make_intnode(ftell(writestream)));
  487. }
  488.  
  489. NODE *lsetwritepos(NODE *arg)
  490. {
  491.     NODE *val = pos_int_arg(arg);
  492.  
  493.     if (NOT_THROWING) {
  494.     fseek(writestream,getint(val),0);
  495.     }
  496.     return(UNBOUND);
  497. }
  498.